//
//  SocketManager.m
//  yang Extension
//
//  Created by wbb on 2020/6/24.
//  Copyright © 2020 于浦洋. All rights reserved.
//

#import "SocketManager.h"
//#import "NSData+Extension.h"

@interface SocketManager ()<NSStreamDelegate>
{
    NSInputStream *inputStream;
    NSOutputStream *outputStream;
}
@property(nonatomic, strong) NSMutableData *bufData;// 当前包内容
@property (nonatomic, assign) NSInteger currentByteLength;//当前包内字节内容的长度
@property (nonatomic, assign) NSInteger byteLength;//获取包长度的4个字节（是否是4个字节）
@end
@implementation SocketManager

+ (instancetype)sharedSocketManager {
    static SocketManager *socketManager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        socketManager = [[SocketManager alloc] init];
    });
    return socketManager;
}

- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode{
    
    NSLog(@"eventCode:%lu",(unsigned long)eventCode);
    switch (eventCode) {
        case NSStreamEventOpenCompleted:
            
            NSLog(@"输入输出流打开完成");
            
            break;
        case NSStreamEventHasBytesAvailable:
            
            NSLog(@"有字节可读");
//            uint8_t buf0[1024];
//            NSInteger len0 = [inputStream read:buf0 maxLength:sizeof(buf0)];
//            NSData *data0 = [NSData dataWithBytes:buf0 length:len0];
            
            [self readData];
            
            break;
        case NSStreamEventHasSpaceAvailable:
            
            NSLog(@"可以发送字节");
//            [self readData];

            break;
        case NSStreamEventErrorOccurred:
            NSLog(@" 连接出现错误%@",aStream.streamError);
            [self closeSocket];
            break;
        case NSStreamEventEndEncountered:
            
            NSLog(@"连接结束");
            
            [self closeSocket];
            break;
        default:
            break;
    }
    
}
- (void)closeSocket {
    // 关闭输入输出流
    [inputStream close];
    [outputStream close];
    
    // 从主运行循环移除
    [inputStream removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
    [outputStream removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
}
/*
 NSString *host = @"";//IP地址;
 int port = @"";//端口号;
 */
- (void)connect:(NSString *)host port:(int)port{
    
    
    
    CFReadStreamRef readStream;
    CFWriteStreamRef writeStream;
    CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)host, port, &readStream, &writeStream);
    
    inputStream = (__bridge NSInputStream *)(readStream);
    outputStream = (__bridge NSOutputStream *)(writeStream);
    
    inputStream.delegate = self;
    outputStream.delegate = self;
    
    [inputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
    [outputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
    
    [inputStream open];
    [outputStream open];
    
}

- (void)sendMsg: (NSString *)msg
{
    NSMutableData *sendData = [NSMutableData dataWithCapacity:0];
    
    /// 所传的内容
    NSData *data = [msg dataUsingEncoding:NSUTF8StringEncoding];
    
    /// 第一个字节传入type
    Byte byte1[1];
    byte1[0] = 0x04;
    
    /// 后面四个字节是内容的长度
    NSInteger dataLength = data.length;
//    int8_t ch[4];
//    for(int32_t i = 0;i<4;i++){
//        ch[i] = ((dataLength >> ((3 - i)*8)) & 0x0ff);
//    }
    /// 大小端转换
    Byte ch[4];
    OSWriteBigInt32(ch, 0, dataLength);
    
    [sendData appendBytes:byte1 length:1];
    [sendData appendBytes:&ch length:sizeof(ch)];
    [sendData appendData:data];
    
    [outputStream write:sendData.bytes maxLength:sendData.length];
}

- (void)readData {
    int dataLenInt = 0;
    if (self.currentByteLength==0) {

        if(self.byteLength==0) {
            self.bufData = nil;
            uint8_t buf1[1];
            NSInteger len1 = [inputStream read:buf1 maxLength:sizeof(buf1)];
            NSData *data1 = [NSData dataWithBytes:buf1 length:len1];
            [self.bufData appendData:data1];

            Byte byte[] = {0x03};
            if ([data1 isEqualToData:[NSData dataWithBytes:byte length:1]]) {
                uint8_t buf2[4];
                NSInteger len2 = [inputStream read:buf2 maxLength:sizeof(buf2)];
                self.byteLength = len2;
                NSData *data2 = [NSData dataWithBytes:buf2 length:len2];
                [self.bufData appendData:data2];
                if (len2<4) {
                    self.currentByteLength = 0;
                }else {
                    self.currentByteLength = CFSwapInt32BigToHost(*(int*)([data2 bytes]));
                    dataLenInt = self.currentByteLength;
                    self.byteLength = 0;
                }
            }
        }
        
        while (self.byteLength>0) {
            uint8_t buf2[4-self.byteLength];
            NSInteger len2 = [inputStream read:buf2 maxLength:sizeof(buf2)];
            NSData *data2 = [NSData dataWithBytes:buf2 length:len2];
            [self.bufData appendData:data2];
            if (len2<4-self.byteLength) {
                self.byteLength = 4-self.byteLength - len2;
            }else {
                NSData *langthData = [self.bufData subdataWithRange:NSMakeRange(1, 4)];
                self.currentByteLength = CFSwapInt32BigToHost(*(int*)([langthData bytes]));
                dataLenInt = self.currentByteLength;
                self.byteLength = 0;
            }
        }
    }

    while (self.currentByteLength>0) {
        uint8_t buf[self.currentByteLength];
        NSInteger len = [inputStream read:buf maxLength:sizeof(buf)];
        NSData *data = [NSData dataWithBytes:buf length:len];
        [self.bufData appendData:data];
        
        if (self.currentByteLength>len) {
            self.currentByteLength = self.currentByteLength - len;
        }else {
            self.currentByteLength = 0;
        }
        
    }
    
    NSData * lastsendData = [self.bufData subdataWithRange:NSMakeRange(5, dataLenInt)];
    NSString * contentStr = [[NSString alloc]initWithData:lastsendData encoding:NSUTF8StringEncoding];
    
    NSLog(@"contentStr == %@",contentStr);
    if (contentStr.length>0) {
        if (self.ContentBlock) {
            self.ContentBlock(contentStr);
        }
    }
    
}
- (void)cleanUpStream:(NSStream *)stream
{
    [stream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [stream close];
    
    stream = nil;
}
- (NSMutableData *)bufData {
    if (!_bufData) {
        _bufData = [[NSMutableData alloc] initWithCapacity:0];
    }
    return _bufData;
}
@end
